package com.mvvm.start.main.mvvm.v.activity

import android.content.res.AssetManager
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import com.google.mlkit.vision.common.InputImage
import com.google.mlkit.vision.face.FaceDetection
import com.google.mlkit.vision.face.FaceDetector
import com.google.mlkit.vision.face.FaceDetectorOptions
import com.mvvm.start.base.utils.loge
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.launch
import java.io.IOException
import java.io.InputStream

/**
 * @功能:
 * @User Lmy
 * @Creat 2022/3/30 13:45
 */
class MLFaceDetectionUtils {
    companion object {
        val instance: MLFaceDetectionUtils by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
            MLFaceDetectionUtils()
        }
    }

    var options: BitmapFactory.Options? = null
    var highAccuracyOpts: FaceDetectorOptions? = null
    var detector: FaceDetector? = null

    constructor() {
        // High-accuracy landmark detection and face classification
        highAccuracyOpts = FaceDetectorOptions.Builder()
            .setPerformanceMode(FaceDetectorOptions.PERFORMANCE_MODE_FAST)
            .setLandmarkMode(FaceDetectorOptions.LANDMARK_MODE_ALL)
            .setClassificationMode(FaceDetectorOptions.CLASSIFICATION_MODE_ALL)
            .build()
        // Real-time contour detection
        val realTimeOpts = FaceDetectorOptions.Builder()
            .setContourMode(FaceDetectorOptions.CONTOUR_MODE_ALL)
            .build()
        options = BitmapFactory.Options().apply {
            // 必须为RGB_565
            inPreferredConfig = Bitmap.Config.RGB_565
        }
        detector = FaceDetection.getClient(highAccuracyOpts!!)
    }

    private var maxTesting = 6
    private var nowIndexTesting = 1
    private var noFaceListPath = mutableListOf<String>()
    private var onFilterSuccess: ((data: MutableList<String>) -> Unit) = {}
    fun filter(
        imagePath: MutableList<String>,
        assets: AssetManager,
        success: (data: MutableList<String>) -> Unit
    ) {
        onFilterSuccess = success
        maxTesting = imagePath.size
        noFaceListPath.clear()
        nowIndexTesting = 1
        MainScope().launch {
            for ((index, value) in imagePath.withIndex()) {
                launch(Dispatchers.IO) {
                    initMlkit(value, detector, assets)
                }
            }
        }
    }


    private fun initMlkit(path: String, detector: FaceDetector?, assets: AssetManager) {
        try {
            var bitmap: Bitmap? = null
            try {
                val inputStream: InputStream =
                    assets.open(path) //filename是assets目录下的图片名
                bitmap = BitmapFactory.decodeStream(inputStream, null, options)
            } catch (e: IOException) {
                e.printStackTrace()
            }
            val image = InputImage.fromBitmap(bitmap!!, 0)
            detector?.process(image)?.apply {
                addOnSuccessListener { faces ->
                    nowIndexTesting++
                    if (faces.size == 0) {
                        noFaceListPath.add(path)
                    }
                    "DetectorSuccess是否存在人脸:${faces.size != 0} 人脸数量=${faces.size} 当前图片Index=$path nowIndexTesting：$nowIndexTesting maxTesting：$maxTesting".loge()
                    if (nowIndexTesting > maxTesting) {
                        onFilterSuccess(noFaceListPath)
                    }
                }
                addOnFailureListener { e ->
                    nowIndexTesting++
                    if (nowIndexTesting > maxTesting) {
                        onFilterSuccess(noFaceListPath)
                    }
                    "detectorFailure${e}".loge()
                }
            }

            "DetectorSuccess 最后".loge()

        } catch (e: Exception) {
            "$e".loge()
        }
    }

}